package com.turing.post.datatranferpmbs.impl;

import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.Socket;
import java.nio.charset.Charset;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import weblogic.javaee.TransactionTimeoutSeconds;

import com.turing.post.cardmanagement.util.ActivateCard;
import com.turing.post.cardmanagement.util.ActivateCardDao;
import com.turing.post.datatranferpmbs.util.PMBSCardDistribute;
import com.turing.post.datatranferpmbs.util.PMBSCardDistributeDao;
import com.turing.post.datatranferpmbs.util.PMBSMchAddTradSummary;
import com.turing.post.datatranferpmbs.util.PMBSMchAddTradSummaryDao;
import com.turing.post.datatranferpmbs.util.PMBSMchTradDetail;
import com.turing.post.datatranferpmbs.util.PMBSMchTradDetailBusiness;
import com.turing.post.datatranferpmbs.util.PMBSMchTradDetailDao;
import com.turing.post.organization.util.MerchantBranchDao;
import com.turing.post.thirdinterface.util.MapMchTradDetail;
import com.turing.post.thirdinterface.util.MapMchTradDetailDao;
import com.turing.post.thirdinterface.util.MapPMBSTradDetail;
import com.turing.post.thirdinterface.util.MapPMBSTradDetailDao;
import com.turing.post.transaction.util.MchAddCardDetail;
import com.turing.post.transaction.util.MchAddCardDetailDao;
import com.turing.post.transaction.util.MchAddTradSummary;
import com.turing.post.transaction.util.MchAddTradSummaryDao;
import com.turing.post.transaction.util.MchHisTradDetail;
import com.turing.post.transaction.util.MchHisTradDetailDao;
import com.turing.post.transaction.util.MchTradDetail;
import com.turing.post.transaction.util.MchTradDetailDao;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.SHA1;

@Stateless(mappedName = "datatranferpmbs.impl.PMBSMchTradDetailBusinessImpl")
@TransactionTimeoutSeconds(value = 3600)
@Remote
@Local
public class PMBSMchTradDetailBusinessImpl implements PMBSMchTradDetailBusiness {

	@EJB(mappedName = "datatranferpmbs.impl.PMBSMchTradDetailDaoImpl")
	private PMBSMchTradDetailDao pMBSMchTradDetailDaoImpl;

	@EJB(mappedName = "datatranferpmbs.impl.PMBSCardDistributeDaoImpl")
	private PMBSCardDistributeDao pMBSCardDistributeDaoImpl;

	@EJB(mappedName = "datatranferpmbs.impl.PMBSMchAddTradSummaryDaoImpl")
	private PMBSMchAddTradSummaryDao pMBSMchAddTradSummaryDaoImpl;

	@EJB(mappedName = "thirdinterface.impl.MapPMBSTradDetailDaoImpl")
	private MapPMBSTradDetailDao mapPMBSTradDetailDaoImpl;

	private boolean checkList(List<?> list) {
		boolean tag = false;
		if (list != null && list.size() > 0) {
			tag = true;
		}
		return tag;
	}

	private String getNewTranCode(String s) {
		if ("1010".equals(s)) {
			return "9010";
		} else if ("1020".equals(s)) {
			return "9020";
		} else if ("1021".equals(s)) {
			return "9011";
		}
		return "";
	}

	@Override
	public void deleteMapPMBSTradDetail() {
		mapPMBSTradDetailDaoImpl.deleteMapPMBSTradDetail();
	}

	@Override
	public void transferPMBSMchAddTradSummary(String date)
			throws PCPSApplicationException {
		List<Object[]> objList = pMBSMchTradDetailDaoImpl
				.getMerchantAndTranDateList(date);
		String merchantNo = "";
		if (objList != null && objList.size() > 0) {
			for (Object[] obs : objList) {
				merchantNo = obs[0].toString();
				String newMrchNo = mapPMBSTradDetailDaoImpl
						.getNewMerchantNoByOldMerchantNo(merchantNo);
				if (newMrchNo != null) {
					// 判断该商户改天是否已经迁移
					MapPMBSTradDetail map = new MapPMBSTradDetail();
					map.setMerchantNo(merchantNo);
					map.setTrandate(date);
					MapPMBSTradDetail serMap = mapPMBSTradDetailDaoImpl
							.getMapPMBSTradDetailByPk(map);
					if (serMap == null) {
						List<PMBSMchAddTradSummary> accList = pMBSMchAddTradSummaryDaoImpl
								.getMchAddTradSummaryByCond(merchantNo, date);
						// 附加交易流水数据
						if (checkList(accList)) {
							int count = accList.size();
							PMBSMchAddTradSummary mtd = null;
							for (int i = 0; i < count; i++) {
								mtd = accList.get(i);
								transferMchAddTradSummary(mtd, newMrchNo);
							}
						}
						// 迁移对照表
						MapPMBSTradDetail mapMtd = new MapPMBSTradDetail();
						mapMtd.setMerchantNo(merchantNo);
						mapMtd.setTrandate(date);
						mapPMBSTradDetailDaoImpl.insert(mapMtd);
					} else {
						// PCPSUtil.Log("delete from mappmbstraddetail where
						// merchantno='"+serMap.getMerchantNo()+"' and
						// trandate='"+serMap.getTrandate()+"';");
					}
				} else {
					System.out.println("未找到新数据库中对应商户号");
				}
			}
		}
	}

	@Override
	public void transferPMBSMchTradDetail(String merchantNo, String date)
			throws PCPSApplicationException {
		// 未传入商户号时按日期处理全部商户
		if (PCPSUtil.isEmpty(merchantNo)) {
			List<Object[]> objList = pMBSMchTradDetailDaoImpl
					.getMerchantAndTranDateList(date);
			if (objList != null && objList.size() > 0) {
				for (Object[] obs : objList) {
					merchantNo = obs[0].toString();
					String newMrchNo = mapPMBSTradDetailDaoImpl
							.getNewMerchantNoByOldMerchantNo(merchantNo);
					if (newMrchNo != null) {
						// 判断该商户改天是否已经迁移
						MapPMBSTradDetail map = new MapPMBSTradDetail();
						map.setMerchantNo(merchantNo);
						map.setTrandate(date);
						MapPMBSTradDetail serMap = mapPMBSTradDetailDaoImpl
								.getMapPMBSTradDetailByPk(map);
						if (serMap == null) {
							// 交易流水（MchTradDetail）
							List<PMBSMchTradDetail> tradList = pMBSMchTradDetailDaoImpl
									.getMchTradDetailList(merchantNo, date);
							// List<PMBSMchAddTradSummary> accList =
							// pMBSMchAddTradSummaryDaoImpl
							// .getMchAddTradSummaryByCond(merchantNo,
							// date);
							List<PMBSCardDistribute> cardList = pMBSCardDistributeDaoImpl
									.getAllCardDistributeByCond(merchantNo,
											date);
							// + "附加商品："
							// + accList.size());
							// 循环历史交易流水
							int count1 = tradList.size();
							PMBSMchTradDetail mtd = null;
							for (int i = 0; i < count1; i++) {
								mtd = tradList.get(i);
								transferMchHisTradDetail(mtd, newMrchNo);
							}
							// // 附加交易流水数据
							// int count2 = accList.size();
							// PMBSMchAddTradSummary mtd2 = null;
							// for (int i = 0; i < count2; i++) {
							// mtd2 = accList.get(i);
							// transferMchAddTradSummary(mtd2, newMrchNo);
							// }
							// 附加卡信息
							int count = cardList.size();
							PMBSCardDistribute mtd3 = null;
							for (int i = 0; i < count; i++) {
								mtd3 = cardList.get(i);
								transferCardDistributeDao(mtd3, newMrchNo);
							}
							// 迁移对照表
							MapPMBSTradDetail mapMtd = new MapPMBSTradDetail();
							mapMtd.setMerchantNo(merchantNo);
							mapMtd.setTrandate(date);
							mapPMBSTradDetailDaoImpl.insert(mapMtd);
						} else {
							// PCPSUtil.Log("delete from mappmbstraddetail where
							// merchantno='"+serMap.getMerchantNo()+"' and
							// trandate='"+serMap.getTrandate()+"';");
						}
					} else {
						System.out.println("未找到新数据库中对应商户号");
					}
				}
			}
			// } else {
			// String newMrchNo = mapPMBSTradDetailDaoImpl
			// .getNewMerchantNoByOldMerchantNo(merchantNo);
			// if (newMrchNo != null) {
			// // 判断该商户改天是否已经迁移
			// MapPMBSTradDetail map = new MapPMBSTradDetail();
			// map.setMerchantNo(merchantNo);
			// map.setTrandate(date);
			// MapPMBSTradDetail serMap = mapPMBSTradDetailDaoImpl
			// .getMapPMBSTradDetailByPk(map);
			// if (serMap == null) {
			// // 交易流水（MchTradDetail）
			// List<PMBSMchTradDetail> tradList = pMBSMchTradDetailDaoImpl
			// .getMchTradDetailList(merchantNo, date);
			// List<PMBSMchAddTradSummary> accList =
			// pMBSMchAddTradSummaryDaoImpl
			// .getMchAddTradSummaryByCond(merchantNo, date);
			// List<PMBSCardDistribute> cardList = pMBSCardDistributeDaoImpl
			// .getAllCardDistributeByCond(merchantNo, date);
			// System.out.println("商户：" + merchantNo + "交易流水："
			// + tradList.size() + "附加流水：" + accList.size()
			// + "附加卡明细：" + cardList.size());
			// // 循环历史交易流水
			// int count = tradList.size();
			// PMBSMchTradDetail mtd = null;
			// for (int i = 0; i < count; i++) {
			// mtd = tradList.get(i);
			// transferMchHisTradDetail(mtd, newMrchNo);
			// }
			// // 附加交易流水数据
			// int count = accList.size();
			// PMBSMchAddTradSummary mtd = null;
			// for (int i = 0; i < count; i++) {
			// mtd = accList.get(i);
			// transferMchAddTradSummary(mtd, newMrchNo);
			// }
			// // 附加卡信息
			// int count = cardList.size();
			// PMBSCardDistribute mtd = null;
			// for (int i = 0; i < count; i++) {
			// mtd = cardList.get(i);
			// transferCardDistributeDao(mtd, newMrchNo);
			// }
			// // 迁移对照表
			// MapPMBSTradDetail mapMtd = new MapPMBSTradDetail();
			// mapMtd.setMerchantNo(merchantNo);
			// mapMtd.setTrandate(date);
			// mapPMBSTradDetailDaoImpl.insert(mapMtd);
			// } else {
			// System.out.println("商户数据已经迁移:" + serMap.getMerchantNo()
			// + "====" + serMap.getTrandate());
			// }
			// } else {
			// System.out.println("未找到新数据库中对应商户号");
			// }
		}

	}

	/**
	 * 设置独立事务，进入打开事务，失败关闭事务
	 */
	// @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
	@EJB(mappedName = "transaction.impl.MchAddTradSummaryDaoImpl")
	private MchAddTradSummaryDao mchAddTradSummaryDaoImpl;

	private void transferMchAddTradSummary(PMBSMchAddTradSummary ad,
			String newMrchNo) throws PCPSApplicationException {
		MchAddTradSummary ma = new MchAddTradSummary();
		ma.setMerchantNo(newMrchNo);// 商户ID varchar(15) Not
		ma.setTranDate(ad.getTranDate());// 帐务日期 date Not Null
		ma.setTranSeqNo(ad.getTranSeqNo());// 流水号 varchar(16) Not Null
		ma.setMrchBrchNo(ad.getMrchBrchNo());// 商户分支机构编号 varchar(20)
		ma.setMrchBrchName(ad.getMrchBrchName());// 商户分支机构名称
		ma.setMrchTellerNo(ad.getMrchTellerNo());// 商户操作员编号
		ma.setMrchTellerName(ad.getMrchTellerName());// 商户操作员名称
		ma.setMrchProdDetailNum(ad.getMrchProdDetailNum());// 商户账单明细条数
		ma.setMrchOtherPaidAmount(ad.getMrchCash());// 现金额 decimal(16,4)
		ma.setMrchAmount(ad.getMrchAmount());// 卡金额 decimal(16,4)
		mchAddTradSummaryDaoImpl.insert(ma);
	}

	@EJB(mappedName = "transaction.impl.MchAddCardDetailDaoImpl")
	private MchAddCardDetailDao mchAddCardDetailDaoImpl;

	private void transferCardDistributeDao(PMBSCardDistribute ad,
			String newMrchNo) throws PCPSApplicationException {
		MchAddCardDetail ma = null;
		ma = new MchAddCardDetail();
		ma.setMerchantNo(newMrchNo);// 商户ID varchar(15) Not
		ma.setTranDate(ad.getTranDate());// 帐务日期 date Not Null
		ma.setTranSeqNo(ad.getTranSeqNo());// 流水号 varchar(16) Not Null
		ma.setCardNo(ad.getCardNo());// 卡号 char(19) Not Null
		ma.setAmount(new BigInteger(ad.getAmount() + ""));// 交易金额
		mchAddCardDetailDaoImpl.insert(ma);
	}

	@EJB(mappedName = "transaction.impl.MchHisTradDetailDaoImpl")
	private MchHisTradDetailDao mchHisTradDetailDaoImpl;

	private void transferMchHisTradDetail(PMBSMchTradDetail mt, String newMrchNo)
			throws PCPSApplicationException {
		MchHisTradDetail m = new MchHisTradDetail();
		m.setMerchantNo(newMrchNo);
		m.setTranDate(mt.getTranDate());
		m.setTranSeqNo(mt.getTranSeqNo());
		m.setCancelTranSeqNo(mt.getCancelTranSeqNo());
		m.setTranCode(getNewTranCode(mt.getTranCode()));// 交易码，需要转换
		m.setTranTime(mt.getTradTime());
		// 商户请求流水为空时
		m.setMrchSeqNo(mt.getMrchSeqNo() == null ? mt.getTranSeqNo() : mt
				.getMrchSeqNo());

		// BusinessType 商户业务类型 varchar(40) Null 老系统无此字段
		// FeeRatio 费率 decimal(4) Null 2013.02.02 老系统无此字段
		m.setCardNo(mt.getCardNo());
		m.setAmount(new BigInteger(mt.getAmount() + ""));

		// Fee 合计扣费额 number(8) Not Null 扣费总额 老系统无此字段
		m.setScorePaidAmount(mt.getScorePaidAmount() == null ? null
				: new BigInteger(mt.getScorePaidAmount() + ""));
		m.setFactScorePaidAmount(mt.getFactScorePaidAmount());

		// AccAckSeqNo 帐户子系统记帐流水号 varchar(40) Null 老系统无此字段
		m.setMrchAbstract(mt.getMrchAbstract());
		m.setMembershipId(mt.getMembershipId());
		m.setVipCardNo(mt.getVipCardNo());

		m.setScoreTranSeqNo(mt.getScoreTranSeqNo());// 积分产生流水号 varchar(24) Null
		// 积分系统产生积分的流水号
		m.setScorePaidTranSeqNo(mt.getScorePaidTranSeqNo());// 积分支付流水号
		// varchar(24) Null
		// 积分系统扣除积分的流水号
		m.setScoreAmount(mt.getScoreAmount());// 本次积分发生 numeric(16,0) Not Null
		// 产生的积分
		m.setScore(mt.getScore());// 渠道积分余额 numeric(16,0) Not Null 交易完成后的积分余额
		m.setReScoreTime(mt.getReScoreTime());// 积分补登时间 date Null
		m.setReScoreOperNo(mt.getReScoreOperNo());// 积分补登操作员 varchar(20) Null
		m.setReScoreRemark(mt.getReScoreRemark());// 积分补登备注 varchar(40) Null
		m.setOtherTranDate(mt.getOtherTranDate());// 退货/被退货交易日期 date Null
		// 支付交易存被退货交易日期，退货交易存原支付交易日期
		m.setOtherTranSeqNo(mt.getOtherTranSeqNo());// 退货/被退货交易流水 char(16) Null

		m.setOtherMrchSeqNo(mt.getOtherMrchSeqNo());// 退货/被退货商户流水号 varchar(40)

		// 老系统无此字段
		// TerminalNo(FK) 终端号 varchar(8) Null POS商户设置
		// TermSettBatchNo 终端批次号 varchar(6) Null POS商户设置
		// TermSeqNo 终端流水号 varchar(6) Null POS商户设置
		// MrchTellerNo 商户操作员 varchar(40) Null
		// MrchBrchNo 商户分支机构 varchar(40) Null
		// AdjustTranDate 调帐/错帐日期 date Null 2013.05.04
		// AdjustTranSeqNo 调帐/被调流水号 varchar(40) Null 2013.05.04
		// AdjustOperId 调帐人ID number Null 2013.05.04
		// AdjustRemark 调帐备注 varchar(60) Null 2013.05.04

		try {
			mchHisTradDetailDaoImpl.insert(m);
		} catch (PCPSApplicationException e) {
			e.printStackTrace();
			PCPSUtil.Log("transferMchHisTradDetail", e);
		}
	}

	@Override
	public List<Object[]> getMchTradDetailTranDateList() {
		return pMBSMchTradDetailDaoImpl.getMchTradDetailTranDateList();
	}

	@EJB(mappedName = "organization.impl.MerchantBranchDaoImpl")
	private MerchantBranchDao merchantBranchDaoImpl;

	@EJB(mappedName = "datatranferpmbs.impl.PMBSMchTradDetailBusinessImpl")
	private PMBSMchTradDetailBusiness pMBSMchTradDetailBusinessImpl;

	@EJB(mappedName = "cardmanagement.impl.ActivateCardDaoImpl")
	private ActivateCardDao acDao;

	@EJB(mappedName = "transaction.impl.MchTradDetailDaoImpl")
	private MchTradDetailDao mchTradDetailDaoImpl;

	@EJB(mappedName = "thirdinterface.impl.MapMchTradDetailDaoImpl")
	private MapMchTradDetailDao mapMchTradDetailDaoImpl;

	/**
	 * 日终后 MchHisTradDetail 表数据--------------------------并行数据
	 */
	@Override
	public void tranferPMBSDataByTranDate(String icNo, String ip, Integer port,
			String tranDate, String merchantNo, boolean tag)
			throws PCPSApplicationException {
		String tranCode = "";
		if (tag) {
			tranCode = PMBSMchTradDetail.TRANCODE_PAID;
		} else {
			tranCode = PMBSMchTradDetail.TRANCODE_PAIDCANCEL;
		}
		// 交易流水
		List<PMBSMchTradDetail> tradDetailList = pMBSMchTradDetailDaoImpl
				.getMchTradDetailListByMerchantNoAndTranDate(merchantNo,
						tranDate, tranCode);
		System.out.println("集合大小：" + tradDetailList.size());
		if (tradDetailList == null && tradDetailList.size() < 1) {
			return;
		}
		String pwd = "00000000";
		String miqi = "0001";
		String type = "01";
		String trankey = "00000000";
		PMBSMchAddTradSummary addTradSumm = null;
		HashMap<String, String> map = merchantBranchDaoImpl
				.getMerchantMapListByMerchantNo(icNo);
		HashMap<String, String> merchantMap = mapPMBSTradDetailDaoImpl
				.getMapMerchant();
		// 交易
		if (tag) {
			for (PMBSMchTradDetail tradDetail : tradDetailList) {
				pMBSMchTradDetailBusinessImpl.pmbsData(tradDetail, map,
						merchantMap, addTradSumm, pwd, miqi, type, trankey, ip,
						port, tag);
			}
		}
		if (!tag) {
			// 撤销交易
			for (PMBSMchTradDetail tradDetail : tradDetailList) {
				pMBSMchTradDetailBusinessImpl.pmbsData(tradDetail, map,
						merchantMap, addTradSumm, pwd, miqi, type, trankey, ip,
						port, tag);
			}
		}
	}

	/**
	 * @param merchantMap
	 * @param _td
	 *            老系统插销流水对象
	 * @param trankey
	 * @param pwd
	 * @return
	 */
	private String getPaidCancelContent(HashMap<String, String> merchantMap,
			PMBSMchTradDetail _td, String trankey, String pwd) {
		StringBuilder sb = new StringBuilder();
		// 新系统交易数据对象
		MchTradDetail mtd = mchTradDetailDaoImpl
				.getMchTradDetailByMrchSeqNoFromMchTradDetail(merchantMap
						.get(_td.getMerchantNo()), _td.getTranDate(), _td
						.getOtherMrchSeqNo());
		sb.append("<?xml version=\"1.0\" encoding=\"gb18030\" ?>");
		sb.append("<TransRequest>");
		sb.append(formatObject("TranCode",
				MchHisTradDetail.TRANCODE_PAID_CANCEL));
		sb.append(formatObject("MerchantNo", mtd.getMerchantNo()));
		sb.append(formatObject("TranTime", PCPSUtil
				.getStringYMDHMSPackedByDate(_td.getTradTime())));// 原交易撤销时间
		sb.append(formatObject("TranDate", PCPSUtil.getPackedYMDString(_td
				.getTranDate())));// 原交易撤销账务日期
		sb.append(formatObject("ReqSeqNo", _td.getMrchSeqNo()));
		sb.append(formatObject("BrchNo", mtd.getMrchBrchNo()));
		sb.append("<ReqBody>");

		sb.append(formatObject("TotalAmount", mtd.getAmount()));
		sb.append(formatObject("OrigTranDate", PCPSUtil.getPackedYMDString(_td
				.getTranDate())));
		sb.append(formatObject("OrigReqSeqNo", mtd.getMrchSeqNo()));// 原请求流水号
		sb.append(formatObject("OrigAckSeqNo", mtd.getTranSeqNo()));// 原应答流水号
		sb.append(formatObject("Remark", "老系统撤销交易"));// 撤销或退货原因
		sb.append("</ReqBody>");
		List<PMBSCardDistribute> cardDisList = pMBSCardDistributeDaoImpl
				.getAllCardDistributeByTranSeqNo(mtd.getMerchantNo(), mtd
						.getTranDate(), mtd.getTranSeqNo());
		sb.append(formatObject("TranMac", getMac(
				MchHisTradDetail.TRANCODE_PAID_CANCEL, mtd.getMerchantNo(), _td
						.getTradTime(), cardDisList, trankey, pwd)));
		sb.append("</TransRequest>");
		System.out.println("撤销报文：" + sb);
		return sb.toString();
	}

	@Override
	@TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRES_NEW)
	public void pmbsData(PMBSMchTradDetail tradDetail,
			HashMap<String, String> map, HashMap<String, String> merchantMap,
			PMBSMchAddTradSummary addTradSumm, String pwd, String miqi,
			String type, String trankey, String ip, Integer port, boolean tag)
			throws PCPSApplicationException {
		List<PMBSCardDistribute> cardDisList = null;
		String imsgxml = "";
		MapMchTradDetail mmtd = new MapMchTradDetail();
		mmtd.setMerchantNo(merchantMap.get(tradDetail.getMerchantNo()));
		mmtd.setTranDate(tradDetail.getTranDate());
		mmtd.setReqSeqNo(tradDetail.getTranSeqNo());
		MapMchTradDetail serMmtd = mapMchTradDetailDaoImpl
				.getMapMchTradDetailByPk(mmtd);
		if (serMmtd != null) {
			imsgxml = "null";
		} else {
			// 交易
			if (tag) {
				if (tradDetail.getTranCode().equals(
						PMBSMchTradDetail.TRANCODE_PAID)) {
					if (map.get(merchantMap.get(tradDetail.getMerchantNo())) != null) {
						// 交易附加流水（MchAddTradSummary）
						addTradSumm = pMBSMchAddTradSummaryDaoImpl
								.getMchAddTradSummaryByKey(tradDetail
										.getMerchantNo(), tradDetail
										.getTranDate(), tradDetail
										.getTranSeqNo());
						// 卡交易明细
						cardDisList = pMBSCardDistributeDaoImpl
								.getAllCardDistributeByTranSeqNo(tradDetail
										.getMerchantNo(), tradDetail
										.getTranDate(), tradDetail
										.getTranSeqNo());
						imsgxml = getPaidContent(tradDetail.getMerchantNo(),
								tradDetail.getTranDate(), tradDetail, pwd,
								miqi, type, addTradSumm, cardDisList, map,
								merchantMap, trankey);
					} else {
						System.out.println("商户"
								+ merchantMap.get(tradDetail.getMerchantNo())
								+ "不存在分支机构!");
					}
				}
			}
			// 撤销交易
			if (!tag) {
				if (tradDetail.getTranCode().equals(
						PMBSMchTradDetail.TRANCODE_PAIDCANCEL)) {
					if (map.get(merchantMap.get(tradDetail.getMerchantNo())) != null) {
						imsgxml = getPaidCancelContent(merchantMap, tradDetail,
								trankey, pwd);
					} else {
						System.out.println("商户"
								+ merchantMap.get(tradDetail.getMerchantNo())
								+ "不存在分支机构!");
					}
				}
			}
		}
		if (!"null".equals(imsgxml) && !PCPSUtil.isEmpty(imsgxml)) {
			String omsgxml = doTran(ip, port, imsgxml);
			Integer respcode = omsgxml.indexOf("<RespCode>00</RespCode>");
			if (respcode > 0) {
				// 已迁移流水
				mapMchTradDetailDaoImpl.insertMapMchTradDetail(mmtd);
			}
		}
		// System.out.println("Start交易流水：" + tradDetail.getCardNo());
	}

	private String getPaidContent(String merchantNo, Date tranDate,
			PMBSMchTradDetail td, String pwd, String miqi, String type,
			PMBSMchAddTradSummary summ, List<PMBSCardDistribute> cardDisList,
			HashMap<String, String> map, HashMap<String, String> merchantMap,
			String trankey) throws PCPSApplicationException {
		StringBuilder sb = new StringBuilder();
		sb.append("<?xml version=\"1.0\" encoding=\"gb18030\" ?>");

		sb.append("<TransRequest>");
		sb.append(formatObject("TranCode", MchHisTradDetail.TRANCODE_PAID));
		sb.append(formatObject("MerchantNo", merchantMap
				.get(td.getMerchantNo())));
		sb.append(formatObject("TranTime", PCPSUtil
				.getStringYMDHMSPackedByDate(td.getTradTime())));
		// <PosNo>00000001</PosNo>
		// <PosSettBatchNo>000001</PosSettBatchNo>
		// <PosSeqNo>031656</PosSeqNo>
		sb.append(formatObject("TranDate", PCPSUtil.getPackedYMDString(td
				.getTranDate())));
		sb.append(formatObject("ReqSeqNo", td.getMrchSeqNo()));
		sb.append(formatObject("BrchNo", map.get(merchantMap.get(td
				.getMerchantNo()))));
		sb.append("<ReqBody>");

		sb.append("<Paid>");
		sb.append(formatObject("TotalAmount", td.getAmount()));
		sb.append(formatObject("CardNum", cardDisList.size()));
		ActivateCard ac = null;
		// 卡明细
		if (checkList(cardDisList)) {
			for (PMBSCardDistribute card : cardDisList) {
				ac = acDao.getActivateCardByCardNo(card.getCardNo());
				if (ac == null) {
					return "null";
				}
				acDao.updateActivateCardPwdByCardNo(card.getCardNo());
				sb.append("<Card>");
				sb.append(formatObject("CardNo", card.getCardNo()));
				sb.append(formatObject("Track2", ac.getTwoTrackContent()));
				sb.append(formatObject("Track3", ac.getThirdTrackContent()));
				sb.append(formatObject("Passwd", pwd));
				sb.append(formatObject("Amount", card.getAmount()));
				sb.append("</Card>");
			}
		}
		sb.append("</Paid>");
		// 会员卡积分或支付,本XML片段可选
		// <MemberShip>
		// <CardNo>会员卡卡号(可选)</CardNo>
		// <Track2>会员卡二磁道信息(可选)</Track2>
		// <Track3>会员卡二磁道信息(可选)</Track3>
		// <!-- (非积分支付时可选或不填) -->
		// <Passwd>会员卡支付密码</Passwd>
		// <!-- (纯预付卡支付时可选或置0) -->
		// <ScorePaidAmount>积分支付发生额(分)</ScorePaidAmount>
		// </MemberShip>

		if (summ != null) {
			sb.append(formatObject("OtherPaidAmount", summ.getMrchCash()));// 现金
			// 交易附加信息,本XML片段可选-->
			sb.append("<Additional>");
			// <Abstract>业务摘要或备注(可选)</Abstract>
			// <!—销售单信息,本XML片段可选-->
			sb.append("<SaleOrder>");
			if (miqi.equals(merchantNo)) {
				// <SaleOrderNo>商户销售单号(可选)</SaleOrderNo>
				sb.append(formatObject("BusinessDetailNum", 1));
				sb.append("<BusinessDetail>");
				sb.append(formatObject("BusinessType", type));
				sb.append(formatObject("BusinessAmount", summ.getMrchCash()
						.add(summ.getMrchAmount())));
				sb.append("</BusinessDetail>");
			} else {
				sb.append(formatObject("BusinessDetailNum", 0));
			}
			sb.append("</SaleOrder>");
			sb.append("</Additional>");
		}

		sb.append("</ReqBody>");
		sb.append(formatObject("TranMac", getMac(
				MchHisTradDetail.TRANCODE_PAID, merchantMap.get(td
						.getMerchantNo()), td.getTradTime(), cardDisList,
				trankey, pwd)));
		sb.append("</TransRequest>");

		return sb.toString();
	}

	public StringBuilder macBuf = null;

	public String getMac(String tranCode, String merchantNo, Date tranTime,
			List<PMBSCardDistribute> cardDisList, String tranKey, String pwd) {
		macBuf = new StringBuilder();
		// 本类
		appendMacField(tranCode);
		appendMacField(merchantNo);
		appendMacField(PCPSUtil.getStringYMDHMSPackedByDate(tranTime));
		// 子类
		generateMacField(cardDisList, pwd);
		macBuf.append(tranKey);
		String macstr = macBuf.toString();
		System.out.println("MAC:" + macstr);
		macstr = new SHA1().getDigestOfString(macstr.getBytes());
		return macstr.toString();
	}

	private void appendMacField(String buff) {
		macBuf.append(PCPSUtil.isEmpty(buff) ? "" : buff.trim());
	}

	/**
	 * 产生计算MAC的域
	 */
	private void generateMacField(List<PMBSCardDistribute> cardDisList,
			String pwd) {
		// 仅处理第1个卡号
		for (PMBSCardDistribute card : cardDisList) {
			appendMacField(card.getCardNo());
			appendMacField(pwd);
			// 只处理第一张卡
			break;
		}
	}

	public static final byte[] PCPSHDR = "PCPS".getBytes();
	public static final String CHARSET = "GB18030";
	public static final int MSGHDRLEN = 6;
	public static final String TRANKEY = "00000000";

	public static final String XML_NODE_TransResponse = "TransResponse";
	public static final String XML_NODE_RespCode = "RespCode";
	public static final String XML_NODE_RespErrMsg = "RespErrMsg";
	public static final String RESPCODE_SUCC = "00";

	/**
	 * 执行远程调用PCPS 发送交易报文
	 * 
	 * @param imsgxml
	 * @return
	 * @throws PCPSApplicationException
	 */
	private String doTran(String pcpssvr, int pcpsport, String imsgxml)
			throws PCPSApplicationException {
		Socket s = null;
		OutputStream out = null;
		InputStream in = null;
		String omsgxml = null;

		try {
			PCPSUtil.Log("BEGIN CONNECT[" + pcpssvr + ":" + pcpsport + "]...");
			s = getPCPSClient(pcpssvr, pcpsport);
			PCPSUtil.Log("END CONNECT[" + pcpssvr + ":" + pcpsport + "]...");
			out = s.getOutputStream();
			in = s.getInputStream();
			byte[] imsg = imsgxml.getBytes(CHARSET);
			out.write(PCPSHDR, 0, 4);
			out.write(PCPSUtil.formatIntegerLeaderZero(imsg.length, MSGHDRLEN),
					0, 6);
			out.write(imsg);
			out.flush();
			byte[] omsghdr = new byte[MSGHDRLEN];
			int rlen = in.read(omsghdr);
			if (rlen != MSGHDRLEN)
				throw new PCPSApplicationException("", "读报文长度失败!");
			int omsglen = Integer.parseInt(new String(omsghdr, Charset
					.forName(CHARSET)));
			byte[] omsg = new byte[omsglen];
			rlen = in.read(omsg);
			if (rlen != omsglen)
				throw new PCPSApplicationException("", "读报文体失败!");
			omsgxml = new String(omsg, Charset.forName(CHARSET));
		} catch (Exception e) {
			PCPSUtil.Log("与服务器通信失败!", e);
			throw new PCPSApplicationException("", "与服务器通信失败!");
		}

		try {
			if (out != null)
				out.close();
			if (in != null)
				in.close();
			if (s != null)
				s.close();
		} catch (Exception e) {
		}

		return omsgxml;
	}

	/**
	 * 创建SSL SOCKET
	 * 
	 * @return
	 * @throws PCPSApplicationException
	 */
	private static Socket getPCPSClient(String pcpssvr, int pcpsport)
			throws PCPSApplicationException {
		try {
			// Create a trust manager that does not validate certificate chains
			final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
				@Override
				public void checkClientTrusted(final X509Certificate[] chain,
						final String authType) {
				}

				@Override
				public void checkServerTrusted(final X509Certificate[] chain,
						final String authType) {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			} };

			// Install the all-trusting trust manager
			final SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, trustAllCerts, new java.security.SecureRandom());
			// Create an ssl socket factory with our all-trusting manager
			final SSLSocketFactory factory = sc.getSocketFactory();

			// sc.setHostnameVerifier(new NulledHostnameVerifier());
			// sc.setTrustManager(new NulledTrustManager());
			// SSLSocketFactory factory = (SSLSocketFactory)
			// sc.getSocketFactory();
			return factory.createSocket(pcpssvr, pcpsport);
		} catch (Exception e) {
			PCPSUtil.Log("connect to PCPS Server failed!...", e);
			throw new PCPSApplicationException("", "连接到服务器失败!");
		}
	}

	private static String formatObject(String xmllabel, Object obj) {
		StringBuilder sb = new StringBuilder();

		sb.append("<");
		sb.append(xmllabel);
		sb.append(">");

		sb.append(obj.toString().trim());

		sb.append("</");
		sb.append(xmllabel);
		sb.append(">");

		return sb.toString();
	}

	// @EJB(mappedName = "transaction.impl.MchAccDetailDaoImpl")
	// private MchAccDetailDao mchAccDetailDaoImpl;
	//
	// private int transferMchAccDetail(MchTradDetail mtd,String newMrchNo)
	// throws PCPSApplicationException {
	// List<PMBSMchAccDetail> accList = pMBSMchAccDetailDaoImpl
	// .getAllPMBSMchAccDetailListByCond(mtd.getMerchantNo(), mtd
	// .getTranDate(), mtd.getTranSeqNo());
	// if (checkList(accList)) {
	// MchAccDetail ma = null;
	// for (PMBSMchAccDetail pa : accList) {
	// ma = new MchAccDetail();
	// // AccSeqNo(UNI) 记帐流水号 varchar(40) Not Null 老系统无此字段
	// // AccSubSeqNo(UNI) 记帐序号 int Not Null 老系统无此字段
	// ma.setMerchantNo(newMrchNo);// 商户ID varchar(15) Not
	// // Null 参考Merchant
	// ma.setTranDate(pa.getTranDate());// 帐务日期 date Not Null
	// ma.setTranSeqNo(pa.getTranSeqNo());// 交易流水号 varchar(16) Not
	//
	// // ma.setCardNo();// 卡号 char(19) Null 参考ActiveCard 老系统无此字段
	// // ma.setMasterAccNo(FK) 主帐号 int Not Null 参考MasterAccount
	// // ma.setSubAccNo(FK) 子帐号 int Not Null 参考SubAccountNo
	// // ma.setOpenBranchNo(FK) 子帐号开户机构 varchar(26) Not Null
	// // ma.setSalesGroupId(FK) 销售员组ID int Null
	// // ma.setPaidAmount();// 消费交易金额 number(8) Not Null 消费正,撤销/冲正/退货负
	// // ma.setDepositAmount 充值交易金额 number(8) Not Null 充值正,撤销/冲正负
	// // ma.setFeeAmount 扣费交易金额 number(8) Not Null 扣费可正可负,撤销为相反数
	// // ma.setBusinessType 业务类型 varchar(40) Null
	// // ma.setFeeRatio 扣费/折扣费率 number Not Null
	//
	// mchAccDetailDaoImpl.insert(ma);
	// }
	// return accList.size();
	// } else {
	// return 0;
	// }
	// }

	// private int transferMchAddTradDetail(MchTradDetail mtd, String newMrchNo)
	// throws PCPSApplicationException {
	// List<PMBSMchAddTradDetail> accList = pMBSMchAddTradDetailDaoImpl
	// .getAllMchAddTradDetailByTranSeqNo(mtd.getMerchantNo(), mtd
	// .getTranDate(), mtd.getTranSeqNo());
	// if (checkList(accList)) {
	// MchAddTradDetail ma = null;
	// for (PMBSMchAddTradDetail ad : accList) {
	// ma = new MchAddTradDetail();
	// ma.setMerchantNo(newMrchNo);// 商户ID varchar(15) Not
	// ma.setTranDate(ad.getTranDate());// 帐务日期 date Not Null
	// ma.setTranSeqNo(ad.getTranSeqNo());// 流水号 varchar(16) Not Null
	// ma.setProdSeqNo(ad.getProdSeqNo());// 产品序号 Int Not Null
	// ma.setMrchProdId(ad.getMrchProdId());// 商户产品 Id varchar(40)
	// ma.setMrchProdName(ad.getMrchProdName());// 商户产品名称
	// ma.setMrchProdQuantity(ad.getMrchProdQuantity().toBigInteger());// 商户产品数量
	// ma.setMrchProdPrice(ad.getMrchProdPrice().toBigInteger());// 商户产品单价
	// ma.setMrchProdAmount(ad.getMrchProdAmount().toBigInteger());// 商户产品总价
	// ma.setMrchProdCost(ad.getMrchProdCost().toBigInteger());// 折扣后价格
	// ma.setMrchProdFactSale(ad.getMrchProdFactSale().toBigInteger());// 产品实际售价
	// ma.setMrchProdProfitSYS(ad.getMrchProdProfitSys()
	// .toBigInteger()); // 邮局成本
	// ma.setMrchProdProfitMCH(ad.getMrchProdProfitMch()
	// .toBigInteger()); // 商户方成本
	// mchAddTradDetailDaoImpl.insert(ma);
	// }
	// return accList.size();
	// } else {
	// return 0;
	// }
	// }
}
